//
//  UUProductManager.m
//  UUCharterSupplier
//
//  Created by ZhangAo on 03/02/2018.
//  Copyright © 2018 UUCharter. All rights reserved.
//

#import "UUProductManager.h"
#import <UUFoundation/UUIncrementDataManager.h>
#import <UUFoundation/DKDataManager.h>
#import "UUProductUtility.h"
#import "UUProductRequestModel.h"
#import "UUProductPackageRequestModel.h"
#import "UUProductPackageUpdateRequestModel.h"
#import "UUProductUpdateRequestModel.h"
#import "UUProductPackageDeleteRequestModel.h"
#import "UUProductDeleteRequestModel.h"
#import "UUProductApplicationToOfflineRequestModel.h"

@interface UUProductManager ()

@property (nonatomic, strong) UUIncrementDataManager *productDataManager;
@property (nonatomic, strong) UUIncrementDataManager *productPackageDataManager;

@end

@implementation UUProductManager

- (instancetype)init {
    self = [super init];
    if (self) {
        self.productDataManager = [UUIncrementDataManager managerWithConfiguration:
                                   [UUIncrementDataManagerConfiguration configurationWithRequestModelClass:[UUProductRequestModel class]
                                                                                            storeContainer:[UUProductUtility productDefaults]]];
        self.productPackageDataManager = [UUIncrementDataManager managerWithConfiguration:
                                          [UUIncrementDataManagerConfiguration configurationWithRequestModelClass:[UUProductPackageRequestModel class]
                                                                                                   storeContainer:[UUProductUtility productDefaults]]];
    }
    
    return self;
}

- (void)asyncUpdateProducts {
    WEAK_SELF();
    [self.productDataManager asyncIncrementUpdateWithCompleteBlock:^(BOOL hadUpdate, NSArray<id> *insert, NSArray<id> *delete, NSError *error) {
        if (hadUpdate) {
            if (insert.count > 0) {
                [weakSelf notifyObserversWithSelector:@selector(productManagerDidUpdateProducts:) withObject:insert];
            } else {
                [weakSelf notifyObserversWithSelector:@selector(productManagerDidRemoveProducts:) withObject:delete];
            }
        }
    }];
}

- (void)asyncUpdateProductPackages {
    WEAK_SELF();
    [self.productPackageDataManager asyncIncrementUpdateWithCompleteBlock:^(BOOL hadUpdate, NSArray<id> *insert, NSArray<id> *delete, NSError *error) {
        if (error == nil && hadUpdate) {
            if (insert.count > 0) {
                [weakSelf notifyObserversWithSelector:@selector(productManagerDidUpdatePackages) withObject:nil];
            }
            
            if (delete.count > 0) {
                [weakSelf notifyObserversWithSelector:@selector(productManagerDidRemovePackages:) withObject:delete];
            }
        }
    }];
}

- (NSArray<NSNumber *> *)fetchProductsWithReviewStatus:(NSArray<NSNumber *> *)reviewStatus
                                          onlineStatus:(NSArray<NSNumber *> *)onlineStatus
                                         carCategoryId:(NSNumber *)carCategoryId {
    NSArray *carCategories = [GetCarCategoryManager() fetchCarCategories];
    NSMutableString *query = [[NSMutableString alloc] initWithString: @"select id from UUProductModel where 1=1 "];
    
    if (reviewStatus.count > 0) {
        [query appendFormat:@" and status in (%@) ", [reviewStatus componentsJoinedByString:@","]];
    }
    
    if (onlineStatus.count > 0) {
        [query appendFormat:@" and onlineStatus in (%@) ", [onlineStatus componentsJoinedByString:@","]];
    }
    
    if (carCategoryId != nil) {
        [query appendFormat:@" and carCategoryId = %@ ", carCategoryId];
    } else {
        [query appendFormat:@" and carCategoryId in (%@) ", [carCategories componentsJoinedByString:@","]];
    }
    
    [query appendString:@" order by updateTime desc "];
    
    NSMutableArray<NSNumber *> *products = [NSMutableArray array];
    [[UUProductModel getUsingLKDBHelper] executeDB:^(FMDatabase * _Nonnull db) {
        FMResultSet *set = [db executeQuery:query];
        while ([set next]) {
            [products addObject:@([set intForColumnIndex:0])];
        }
        [set close];
    }];
    
    return products;
}

- (UUProductModel *)fetchProductModelWithProductId:(NSNumber *)productId {
    return (UUProductModel *)[self.productDataManager fetchModelWithPrimaryKeyValue:productId];
}

- (void)asyncUpdateProductWithProductId:(NSNumber *)productId
                          carCategoryId:(NSNumber *)carCategoryId
                                fleetId:(NSNumber *)fleetId
                                   spec:(NSArray<UUProductSpecModel *> *)spec
                          completeBlock:(void (^)(NSError *error))completeBlock {
    UUProductUpdateRequestModel *requestModel;
    if (productId == nil) {
        requestModel = [UUProductAddRequestModel new];
    } else {
        requestModel = [UUProductUpdateRequestModel new];
    }
    
    requestModel.productId = productId;
    requestModel.carCategoryId = carCategoryId;
    requestModel.fleetId = fleetId;
    requestModel.spec = spec;
    
    WEAK_SELF();
    [[DKDataManager new] requestWithRequestModel:requestModel completedBlock:^(DKResponseModel *responseModel, NSError *error) {
        if (error == nil) {
            [weakSelf asyncUpdateProducts];
        }
        
        BLOCK_SAFE_CALLS(completeBlock, error);
    }];
}

- (void)asyncDeleteProductWithProductId:(NSNumber *)productId completeBlock:(void (^)(NSError *error))completeBlock {
    UUProductDeleteRequestModel *requestModel = [UUProductDeleteRequestModel new];
    requestModel.productId = productId;
    
    WEAK_SELF();
    [[DKDataManager new] requestWithRequestModel:requestModel completedBlock:^(DKResponseModel *responseModel, NSError *error) {
        if (error == nil) {
            [weakSelf asyncUpdateProducts];
        }
        
        BLOCK_SAFE_CALLS_In_Main_Queue(completeBlock, error);
    }];
}

- (NSArray<id> *)fetchProductPackagesWithPackageType:(UUProductPackageType)packageType {
    NSArray<NSNumber *> *packages = [UUProductPackageModel searchColumn:@"id"
                                                                  where:@{ @"type" : @(packageType) }
                                                                orderBy:@"updateTime desc"
                                                                 offset:0
                                                                  count:0];
    return packages;
}

- (UUProductPackageModel *)fetchProductPackageModelWithPackageId:(NSNumber *)packageId {
    return (UUProductPackageModel *)[self.productPackageDataManager fetchModelWithPrimaryKeyValue:packageId];
}

- (void)asyncUpdatePackageWithPackageId:(NSNumber *)packageId
                            packageType:(UUProductPackageType)packageType
                                   name:(NSString *)name
                                   desc:(NSString *)desc
                                minTime:(NSString *)minTime
                                maxTime:(NSString *)maxTime
                              isHalfDay:(BOOL)isHalfDay
                               allDayKm:(NSInteger)allDayKm
                             allDayHour:(NSInteger)allDayHour
                              halfDayKm:(NSInteger)halfDayKm
                            halfDayHour:(NSInteger)halfDayHour
                          completeBlock:(void (^)(NSError *))completeBlock {
    UUProductPackageUpdateRequestModel *requestModel = nil;
    if (packageId == nil) {
        requestModel = [UUProductPackageAddRequestModel new];
    } else {
        requestModel = [UUProductPackageUpdateRequestModel new];
        requestModel.packageId = packageId;
    }
    
    requestModel.type = packageType;
    requestModel.name = name;
    requestModel.desc = desc;
    requestModel.minTime = minTime;
    requestModel.maxTime = maxTime;
    requestModel.isHalfDay = isHalfDay;
    requestModel.allDayKm = allDayKm;
    requestModel.allDayHour = allDayHour;
    requestModel.halfDayKm = halfDayKm;
    requestModel.halfDayHour = halfDayHour;
    
    WEAK_SELF();
    [[DKDataManager new] requestWithRequestModel:requestModel completedBlock:^(DKResponseModel *responseModel, NSError *error) {
        if (error == nil) {
            [weakSelf asyncUpdateProductPackages];
        }
        
        BLOCK_SAFE_CALLS_In_Main_Queue(completeBlock, error);
    }];
}

- (void)asyncDeletePackageWithPackageId:(NSNumber *)packageId completeBlock:(void (^)(NSError *error))completeBlock {
    UUProductPackageDeleteRequestModel *requestModel = [UUProductPackageDeleteRequestModel new];
    requestModel.packageId = packageId;
    
    WEAK_SELF();
    [[DKDataManager new] requestWithRequestModel:requestModel completedBlock:^(DKResponseModel *responseModel, NSError *error) {
        if (error == nil) {
            [weakSelf asyncUpdateProductPackages];
        }
        
        BLOCK_SAFE_CALLS_In_Main_Queue(completeBlock, error);
    }];
}

- (void)asyncApplicationToOfflineWithProductId:(NSNumber *)productId completeBlock:(void (^)(NSError *error))completeBlock {
    UUProductApplicationToOfflineRequestModel *requestModel = [UUProductApplicationToOfflineRequestModel new];
    requestModel.id = productId;
    
    WEAK_SELF();
    [[DKDataManager new] requestWithRequestModel:requestModel completedBlock:^(DKResponseModel *responseModel, NSError *error) {
        if (error == nil) {
            [weakSelf asyncUpdateProducts];
        }
        
        BLOCK_SAFE_CALLS_In_Main_Queue(completeBlock, error);
    }];
}

- (void)asyncCancelApplicationToOfflineWithProductId:(NSNumber *)productId completeBlock:(void (^)(NSError *error))completeBlock {
    UUProductCancelApplicationToOfflineRequestModel *requestModel = [UUProductCancelApplicationToOfflineRequestModel new];
    requestModel.id = productId;
    
    WEAK_SELF();
    [[DKDataManager new] requestWithRequestModel:requestModel completedBlock:^(DKResponseModel *responseModel, NSError *error) {
        if (error == nil) {
            [weakSelf asyncUpdateProducts];
        }
        
        BLOCK_SAFE_CALLS_In_Main_Queue(completeBlock, error);
    }];
}

@end
